import { _decorator, Component, error, Node } from 'cc';
import Singleton from './Singleton';
const { ccclass, property } = _decorator;

class Listener{
private _msgName:string='';
private _target:any=null;
get target(){
    return this._target;
}
private _cb:Function=null;
get cb(){
    return this._cb;
}
private _isOnce:Boolean=null;
get isOnce(){
    return this._isOnce;
}
    constructor(msgName:string,taget:any,cb:Function,isOnce:boolean){
        this._msgName = msgName;
        this._target = taget;
        this._cb = cb;
        this._isOnce = isOnce;
    }
    isEquals(listener: Listener) {
        return this._msgName == listener._msgName
            && this._cb == listener._cb
            && this._target == listener._target;
    }
}
@ccclass('Emitter')
export class Emitter extends Singleton<Emitter>(){
    private _mapListener:Map<string,Listener[]> = new Map();
    On(msgName:string,target:any,cb:Function,isOnce:boolean = false){
        if(msgName.length<=0||!target||!cb){
            return;
        }
        let arrListener=this._mapListener.get(msgName);
        if(!arrListener){
            arrListener=[];
            this._mapListener.set(msgName,arrListener);
        }
        let listener=new Listener(msgName,target,cb,isOnce);
                //判断这个对象的这个函数绑定的listener是否已经存在了，如果是，不需要注册。
        for(let listenerIn of arrListener){
            if(listener.isEquals(listenerIn)){
                error('已经注册过了');
                return;
            }
        }
        arrListener.push(listener);
    }
    Once(msgName:string,target:any,cb:Function){
        this.On(msgName,target,cb,true)
    }
    emit(msgName:string,...rest:any[]){
        if(msgName.length<=0){
            return;
        }
        let args=Array.prototype.slice.call(arguments,1);
                let arrListener = this._mapListener.get(msgName);
        if(!arrListener){
            //如果都没有注册，那么都不处理
            return;
        }
        for(let i=0;i<=arrListener.length;i++){
            let listener=arrListener[i];
            listener.cb(args);
            if(listener.isOnce){
                arrListener.splice(i--,1);
            }
        }
        if(arrListener.length <=0){
            this._mapListener.delete(msgName);
        }
    }
    off(...rest:any[]){
        let args=Array.from(arguments);
        let length=args.length;
        if(length<=0){
            this._mapListener.clear();
        }
        if(typeof args[0] != 'string'){
            error('清除消息第一个参数必须是字符串');
            return;
        }
        let arrListener=this._mapListener.get(args[0]);
        if(length===1){
            //let arrListener=this._mapListener.get(args[0]);
            this._mapListener.delete(args[0]);
            return;
        }
        if(length===2){
            for (let i = 0; i < arrListener.length; i++) {
                if (args[1] == arrListener[i].target) {
                    arrListener.splice(i--, 1);
                }
            }
            //如果空了，那么删掉
            if (arrListener.length <= 0) {
                this._mapListener.delete(args[0]);
            }
            return;
        }
        if(length===3){
            for (let i = 0; i < arrListener.length; i++) {
                if (args[1] == arrListener[i].target&&args[2] == arrListener[i].cb) {
                    arrListener.splice(i,1);  //因为不应该存在一个消息里面注册了同个对象的同个函数多次。 
                    break;
                }
            }
            //return;
        }
        if(arrListener.length <=0){
            this._mapListener.delete(args[0]);
        }
    }

}

